package com.lry.web;

import com.lry.anno.ExceptionListener;
import com.lry.handler.ExceptionHandler;
import com.lry.properties.EaNoticeProperties;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class EaHandlerExceptionResolver implements HandlerExceptionResolver {

    private final ExceptionHandler exceptionHandler;

    private final EaNoticeProperties eaNoticeProperties;

    private final CurrentRequetBodyResolver currentRequetBodyResolver;

    private final CurrentRequestHeaderResolver currentRequestHeaderResolver;

    public EaHandlerExceptionResolver(ExceptionHandler exceptionHandler,
                                          CurrentRequetBodyResolver currentRequetBodyResolver,
                                          CurrentRequestHeaderResolver currentRequestHeaderResolver,
                                          EaNoticeProperties eaNoticeProperties) {
        this.exceptionHandler = exceptionHandler;
        this.currentRequestHeaderResolver = currentRequestHeaderResolver;
        this.currentRequetBodyResolver = currentRequetBodyResolver;
        this.eaNoticeProperties = eaNoticeProperties;
    }

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        RuntimeException e = null;
        if (ex instanceof RuntimeException)
            e = (RuntimeException) ex;
//        HandlerMethod handlerMethod = null;
//        if (handler instanceof HandlerMethod)
//            handlerMethod = (HandlerMethod) handler;
//        ExceptionListener listener = getListener(handlerMethod);
//        if (listener != null && e != null && handler != null) {
//            exceptionHandler.createHttpNotice(e, request.getRequestURI(), getParams(request), getRequestBody(),
//                    getHeader(request));
//        }

        if (e != null && handler != null) {
            exceptionHandler.createHttpNotice(e, request.getRequestURI(), getParams(request), getRequestBody(),
                    getHeader(request));
        }
        return null;
    }

    private Map<String, String> getParams(HttpServletRequest request) {
        Map<String, String> map = new HashMap<String, String>();
        request.getParameterMap().forEach((x, y) -> map.put(x, String.join(" , ", Arrays.asList(y))));
        return map;
    }

    private String getRequestBody() {
        return currentRequetBodyResolver.getRequestBody();
    }

    private Map<String, String> getHeader(HttpServletRequest request) {
        return currentRequestHeaderResolver.headers(request, eaNoticeProperties.getIncludeHeaderName());
    }

    private ExceptionListener getListener(HandlerMethod handlerMethod) {
        ExceptionListener listener = handlerMethod.getMethodAnnotation(ExceptionListener.class);
        if (listener == null)
            listener = handlerMethod.getBeanType().getAnnotation(ExceptionListener.class);
        return listener;
    }
}
